#include <iostream>
#include <memory>
#include <utility>

struct Gadget {
    Gadget() {
        std::cout << "Gadget(): 默认构造\n";
    }

    Gadget(const Gadget&) {
        std::cout << "Gadget(const Gadget&): 拷贝构造\n";
    }

    Gadget(Gadget&&) noexcept {
        std::cout << "Gadget(Gadget&&): 移动构造\n";
    }
};

// 工厂函数：利用完美转发透传构造参数
template <typename T, typename... Args>
std::unique_ptr<T> make_unique_forward(Args&&... args) {
    return std::unique_ptr<T>(new T(std::forward<Args>(args)...));
}

int main() {
    std::cout << "完美转发示例\n\n";

    std::cout << "1) 通过完美转发调用默认构造:\n";
    auto g1 = make_unique_forward<Gadget>(); // 调用 Gadget()

    std::cout << "\n2) 通过完美转发接受左值参数:\n";
    Gadget original;
    auto g2 = make_unique_forward<Gadget>(original); // 触发拷贝构造

    std::cout << "\n3) 通过完美转发接受右值参数:\n";
    auto g3 = make_unique_forward<Gadget>(Gadget{}); // 触发移动构造

    std::cout << "\n4) 通过 std::move(original) 保留将亡值语义:\n";
    auto g4 = make_unique_forward<Gadget>(std::move(original)); // 触发移动构造

    return 0;
}